package com.wugh.fast.module.mapper.interceptor.plugin;


import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

/**
 * 说明: 插件开关
 *
 * @author wugh
 * @date 2018-11-30 16:19
 */
public class PluginSwitch {
    private static final String GLOBAL = "ALL_ENTITY";

    /**
     * 有记录,代表关闭
     */
    private static final ThreadLocal<ConcurrentHashMap<Class<? extends CustomizePlugin>, ConcurrentSkipListSet<String>>> local = new InheritableThreadLocal<ConcurrentHashMap<Class<? extends CustomizePlugin>, ConcurrentSkipListSet<String>>>() {
        /**
         * Child threads should get a copy of the parent's hashmap.
         */
        @Override
        protected ConcurrentHashMap<Class<? extends CustomizePlugin>, ConcurrentSkipListSet<String>> childValue(ConcurrentHashMap<Class<? extends CustomizePlugin>, ConcurrentSkipListSet<String>> parentValue) {
            if (parentValue == null) {
                return null;
            } else {
                return new ConcurrentHashMap<>(parentValue);
            }
        }
    };

    /**
     * 清空控制
     */
    public static void clear() {
        local.remove();
    }

    public static void init() {
        local.set(new ConcurrentHashMap<>(10));
    }

    public static ConcurrentSkipListSet<String> getSwitch(Class<? extends CustomizePlugin> clazz) {
        ConcurrentHashMap<Class<? extends CustomizePlugin>, ConcurrentSkipListSet<String>> map = local.get();
        if (map == null) {
            synchronized (PluginSwitch.class) {
                map = local.get();
                if (map == null) {
                    map = new ConcurrentHashMap<>(10);
                    local.set(map);
                }
            }
        }
        return map.computeIfAbsent(clazz, set -> new ConcurrentSkipListSet<>());
    }

    /**
     * 关闭指定插件
     *
     * @param clazz
     */
    public static void close(Class<? extends CustomizePlugin> clazz) {
        getSwitch(clazz).add(GLOBAL);
    }

    /**
     * 关闭指定插件的指定实体类
     *
     * @param clazz
     * @param entityClass
     */
    public static void close(Class<? extends CustomizePlugin> clazz, Class<?> entityClass) {
        getSwitch(clazz).add(entityClass.getName());
    }

    public static void open(Class<? extends CustomizePlugin> clazz) {
        getSwitch(clazz).clear();
    }

    public static void open(Class<? extends CustomizePlugin> clazz, Class<?> entityClass) {
        getSwitch(clazz).remove(entityClass.getName());
    }

    public static boolean checkWork(Class<? extends CustomizePlugin> clazz, Class<?> entityClass) {
        ConcurrentSkipListSet<String> set = getSwitch(clazz);
        return !set.contains(GLOBAL) && !set.contains(entityClass.getName());
    }
}
